﻿namespace AStartAlgorithm.Comm
{
    public enum MapType
    {
        /// <summary>
        /// 障碍
        /// </summary>
        Obstacle = -1,
        /// <summary>
        /// 空白空间
        /// </summary>
        Empty = 0,
        /// <summary>
        /// 起点
        /// </summary>
        Star = 1,
        /// <summary>
        /// 终点
        /// </summary>
        End = 2,
        /// <summary>
        /// 显示文本
        /// </summary>
        ShowValue = 3
    }


    public class CommServer
    {
        int map_row = 15;
        int map_col;
        public int[,] Map { get; private set; }

        readonly Color color_Empty = Color.FromArgb(255, 231, 186);
        readonly Color color_Obstacle = Color.FromArgb(209, 95, 238);
        readonly Color color_Point = Color.LightCoral;

        public void InitMap(Panel panel)
        {
            int item_height = (panel.Height / map_row);
            int item_width = item_height;
            map_col = panel.Width / item_width;//修改为正方形地图    
            panel.Width = item_width * map_col;
            panel.Height = item_height * map_row;

            Map = new int[map_col, map_row];
            if (File.Exists("map.json"))
            {
                var json = File.ReadAllText("map.json");
                var data = System.Text.Json.JsonSerializer.Deserialize<List<int>>(json)!;
                Map = ArrayParse.Row2ArrT(data.ToArray(), Map);
            }
            else
            {
                for (int row = 0; row < map_row; row++)
                {
                    for (int col = 0; col < map_col; col++)
                    {
                        Map[col, row] = 0;
                    }
                }
            }
            DramMap(panel);
        }

        public void SaveMap()
        {
            var data = ArrayParse.Arr2RowT(Map);
            File.WriteAllText("map.json", System.Text.Json.JsonSerializer.Serialize(data));
        }

        /// <summary>
        /// 绘制地图
        /// </summary>
        public void DramMap(Panel panel)
        {
            int item_height = (panel.Height / map_row);
            int item_width = item_height;

            List<Label> labels = new List<Label>();
            for (int row = 0; row < map_row; row++)
            {
                for (int col = 0; col < map_col; col++)
                {
                    Label label = new Label();
                    label.Name = $"label_{col}_{row}";
                    label.BorderStyle = BorderStyle.FixedSingle;
                    label.Width = item_width;
                    label.Height = item_height;
                    label.Location = new Point(col * item_width, row * item_height);
                    label.TextAlign = ContentAlignment.MiddleCenter;
                    label.Click += SetObstacle;
                    int value = Map[col, row];
                    if (value >= 10)
                    {
                        SetItemStyle(label, MapType.ShowValue, value.ToString());
                    }
                    else
                    {
                        SetItemStyle(label, (MapType)value);
                    }
                    labels.Add(label);
                }
            }
            panel.SuspendLayout();
            panel.Visible = false;
            panel.Controls.Clear();
            panel.Controls.AddRange(labels.ToArray());
            panel.ResumeLayout(false);
            panel.PerformLayout();
            panel.Visible = true;
        }

        /// <summary>
        /// 设置障碍点|起点、终点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>                                  
        private void SetObstacle(object? sender, EventArgs e)
        {
            MouseEventArgs mouse_e = (MouseEventArgs)e;
            var label = sender as Label;
            if (label == null) return;

            var infos = label.Name.Split('_');
            int col = int.Parse(infos[1]);
            int row = int.Parse(infos[2]);
            var value = Map[col, row];

            //鼠标左键
            if (mouse_e.Button == MouseButtons.Left)
            {
                label.Text = "";
                if (value == (int)MapType.Empty)
                {
                    Map[col, row] = -1;
                    SetItemStyle(label, MapType.Obstacle);
                }
                else
                {
                    Map[col, row] = 0;
                    SetItemStyle(label, MapType.Empty);
                }
            }
            //鼠标右键
            else if (mouse_e.Button == MouseButtons.Right)
            {
                if (value == (int)MapType.Obstacle)
                {
                    //墙，不处理
                }
                else if (value == (int)MapType.Empty)
                {
                    //空白-->起点
                    Map[col, row] = (int)MapType.Star;
                    SetItemStyle(label, MapType.Star);
                }
                else if (value == (int)MapType.Star)
                {
                    //起点-->终点
                    Map[col, row] = (int)MapType.End;
                    SetItemStyle(label, MapType.End);
                }
                else if (value == (int)MapType.End)
                {
                    Map[col, row] = (int)MapType.Star;
                    SetItemStyle(label, MapType.Star);
                }
            }
        }

        /// <summary>
        /// 设置背景色
        /// </summary>
        /// <param name="label"></param>
        /// <param name="type"></param>
        private void SetItemStyle(Label label, MapType type, string text = "")
        {
            label.Font = new Font("Microsoft YaHei UI", 9F);
            label.ForeColor = Color.Black;
            if (type == MapType.Obstacle)
            {
                label.BackColor = color_Obstacle;
                label.Text = "";
            }
            else if (type == MapType.Empty)
            {
                label.BackColor = color_Empty;
                label.Text = "";
            }
            else if (type == MapType.Star)
            {
                label.BackColor = color_Point;
                label.Text = "A";
            }
            else if (type == MapType.End)
            {
                label.BackColor = color_Point;
                label.Text = "B";
            }
            else if (type == MapType.ShowValue)
            {
                label.Font = new Font("Microsoft YaHei UI", 6F);
                label.BackColor = color_Empty;
                label.Text = text;
            }
        }

        /// <summary>
        /// 绘制结果使用
        /// </summary>
        /// <param name="panel"></param>
        /// <param name="lineRes"></param>
        public void DramMap(Panel panel, List<UnitPonit> lineRes)
        {
            int item_height = (panel.Height / map_row);
            int item_width = item_height;
            var endPoint = lineRes[0];

            //防止更新终点
            Map[endPoint.x, endPoint.y] = (int)MapType.End;

            List<Label> labels = new List<Label>();
            for (int row = 0; row < map_row; row++)
            {
                for (int col = 0; col < map_col; col++)
                {
                    Label label = new Label();
                    label.Name = $"label_{col}_{row}";
                    label.BorderStyle = BorderStyle.FixedSingle;
                    label.Width = item_width;
                    label.Height = item_height;
                    label.Location = new Point(col * item_width, row * item_height);
                    label.TextAlign = ContentAlignment.MiddleCenter;
                    label.Click += SetObstacle;
                    int value = Map[col, row];
                    if (value >= 10)
                    {
                        SetItemStyle(label, MapType.ShowValue, value.ToString());
                    }
                    else
                    {
                        SetItemStyle(label, (MapType)value);
                    }
                    //显示路径
                    if (lineRes.Any(t => t.x == col && t.y == row))
                    {
                        label.Font = new Font("Microsoft YaHei UI", 7F, FontStyle.Bold);
                        label.ForeColor = Color.Red;
                    }
                    labels.Add(label);
                }
            }
            panel.SuspendLayout(); // 暂停布局计算
            panel.Visible = false; // 临时隐藏容器（减少中间绘制）
            panel.Controls.Clear();
            panel.Controls.AddRange(labels.ToArray());
            panel.ResumeLayout(false); // 恢复布局（false表示不立即重绘）
            panel.PerformLayout();     // 手动触发一次布局计算
            panel.Visible = true;      // 显示容器（一次性绘制所有控件）
        }

        /// <summary>
        /// 重新开始
        /// </summary>
        /// <param name="panel"></param>
        public void Reset(Panel panel)
        {
            for (int x = 0; x < map_col; x++)
            {
                for (int y = 0; y < map_row; y++)
                {
                    if (Map[x, y] > 3)
                    {
                        Map[x, y] = (int)MapType.Empty;
                    }
                }
            }
            DramMap(panel);
        }
    }
}
